import { Toolkit } from "../Framework/scripts/Toolkit";
import Watcher from "../Framework/scripts/Watcher";
import EffectMgr from "./EffectMgr";
import GameAssetMgr from "./GameAssetMgr";
import Item from "./Item";
import Top from "./Top";

const { ccclass, property } = cc._decorator;

@ccclass
export default class ItemPanel extends cc.Component {

    /** 点击Item 飞向列表 */
    public static readonly EVENT_FLY_ITEM = "EVENT_FLY_ITEM";

    private score:number = 0;

    @property(cc.Sprite)
    comb_slider:cc.Sprite = null;
    mul = 0;

    @property(cc.Sprite)
    mulSprite:cc.Sprite = null;

    @property(cc.Sprite)
    mulTipSprite:cc.Sprite =  null;

    @property(cc.Sprite)
    comb:cc.Sprite = null;
    @property([cc.SpriteFrame])
    combsfs:cc.SpriteFrame[] = [];

    onLoad() {
        Watcher.on(ItemPanel.EVENT_FLY_ITEM, this, this.animation);
        this.mulSprite.node.scale = 0;
        this.mulTipSprite.node.parent.active = false;
    }

    getPos(index) {
        const sx = -282.711;
        const sy = 17.084;
        const interval = 100.87 * 0.7;
        return cc.v2(sx + interval * index, sy);
    }

    items: Item[] = [];
    animation(item: Item) {

        const context = this;
        const node = item.node;

        //游戏结束
        if (context.node.childrenCount == 9) {
            context.gameFailure();
            return;
        }

        //fly动画
        let fly = (pos: cc.Vec2, index = -1) => {
            //切换坐标系
            if (node.parent != context.node) {
                let worldpos = node.convertToWorldSpaceAR(cc.Vec2.ZERO);
                let localpos = context.node.convertToNodeSpaceAR(worldpos);
                node.setParent(context.node);
                index != -1 && node.setSiblingIndex(index);
                node.setPosition(localpos);
            }
            //芜湖~ 起飞~
            if (node.getNumberOfRunningActions() > 0)
                node.stopAllActions();
            cc.tween(node).to(0.3, { scale: 0.7, x: pos.x, y: pos.y }).call(context.flyComplete.bind(context, item)).start();
        }

        let index = -1;
        //判读是否存在相同的对象
        for (let i = context.items.length - 1; i >= 0; i--) {
            let e = context.items[i];
            //当存在相同对象时 位置洗牌
            if (e.gid === item.gid) {
                index = context.node.children.indexOf(e.node) + 1;
                //后排集体向后移动
                for (let i = index; i < context.node.childrenCount; i++) {
                    let pos = context.getPos(i + 1);
                    let t = context.node.children[i];

                    // if (t.getNumberOfRunningActions() > 0) {
                    //     t.stopAllActions();
                    //     if (t.scale != 0.7) t.scale = 0.7;  //强制完成动作
                    // }
                    cc.tween(t).to(0.2, { x: pos.x, y: pos.y }).start();
                }
                //追加到相同对象的尾部
                let pos = context.getPos(index);
                fly(pos, index);
                break;
            }
        }

        //不存在相同的时候 尾部追加
        if (index == -1) {
            let pos = context.getPos(this.node.childrenCount);
            fly(pos);
        }
    }



    flyComplete(item: Item) {

        Toolkit.logTrace(`fly item ${item.gid}`);
        //记录
        this.items.push(item);


        let items = [];
        this.items.find((e) => {
            if (e.gid === item.gid) {
                items.push(e);
                //一次只取 3个完成 连线
                if (items.length == 3)
                    return true;
            }
        });

        //达到条件
        if (items.length == 3) {

            Toolkit.logTrace(`line succeed: ${item.gid}`);

            //播放消除特效
            let n = [];
            n.push(...items.map(e => {
                return e.node
            }));
            Watcher.dispatch(EffectMgr.PLAY_CLEAN_ANIM, n);

            //倍数刷新
            this.addMul();
            let add = this.mul * 10;

            //UI刷新
            this.score += add;
            Watcher.dispatch(Top.CHANGE_SCORE,this.score,240);

            //显示得分
            this.showMul();

            //从items中移除
            items.forEach(e => {
                let index = this.items.indexOf(e);
                if (index != -1) {
                    let t = this.items.splice(index, 1);
                    t[0].node.removeFromParent();
                    t[0].node.destroy();
                }
            });

            //后续列表向左移动
            const context = this;
            setTimeout(() => {
                for (let i = 0; i < this.node.childrenCount; i++) {
                    let pos = context.getPos(i);
                    let t = context.node.children[i];

                    // if (t.getNumberOfRunningActions() > 0) {
                    //     t.stopAllActions();
                    //     if (t.scale != 0.7) t.scale = 0.7;
                    // }
                    cc.tween(t).to(0.2, { x: pos.x, y: pos.y }).start();
                }
            }, 240);
        }

        setTimeout(() => {
            if (this.node.childrenCount === 9) {
                this.gameFailure();
                return;
            }
        }, 300);
    }

    gameFailure() {
        Toolkit.logTrace("game failure.. ");

    }

    addMul(){
        this.mul = Math.min(this.mul + 1,4);
        this.dur = 10;
    }

    showMul( ){
        this.comb.spriteFrame = this.combsfs[Math.min(this.combsfs.length-1,this.mul)];
        this.mulSprite.spriteFrame = GameAssetMgr.instance.getSpriteByID(this.mul.toString());
        this.mulTipSprite.spriteFrame = this.mulSprite.spriteFrame;
        this.mulTipSprite.node.parent.active = true;
        this.mulSprite.node.getNumberOfRunningActions() > 0 && this.mulSprite.node.stopAllActions();
        this.mulSprite.node.scale = 0.8;
        cc.tween(this.mulSprite.node).to(0.12,{scale:1.0},cc.easeBackOut()).delay(1.2).to(0.2,{scale:0.0}).start();
    }

    dur = 0;
    update(dt){

        if(this.dur < 0){
            this.mul = 0;
            this.mulTipSprite.node.parent.active = false;
            this.comb.spriteFrame = this.combsfs[0];
            return;
        }
        this.dur -= dt;
        let f = Toolkit.Clamp( this.dur * 1.0 / 10.0, 0.0,1.0);
        this.comb_slider.fillRange = f;
    }
}
